﻿using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Channels;

using MockingBird.Simulator.Framework;
using MockingBird.Simulator.Interceptors.Wcf.Contracts;

namespace MockingBird.Simulator.Interceptors.Wcf.SimulatorService
{
    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerSession, UseSynchronizationContext = false, ValidateMustUnderstand = false)]
    public sealed class SimulatorService : IOneWay, IOneWayDuplex, IOneWaySession, ITwoWay, ITwoWayVoid
    {
        #region IOneWay Members

        void IOneWay.ProcessMessage(Message message)
        {
            Trace.WriteLine("IOneWay.ProcessMessage");
            try
            {
                FrameworkFacade.ProcessRequest(message, false);
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                throw;
            }

        }

        #endregion

        #region IOneWayDuplex Members

        void IOneWayDuplex.ProcessMessage(Message message)
        {
            Trace.WriteLine("IOneWayDuplex.ProcessMessage");
            try
            {
                Message outMsg = FrameworkFacade.ProcessRequest(message, true);
                Trace.WriteLine("Getting current callback channel");
                IOneWay callbackChannel = OperationContext.Current.GetCallbackChannel<IOneWay>();
                Trace.WriteLine("Invoking callback channel to process message");
                callbackChannel.ProcessMessage(outMsg);

            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                throw;
            }
        }

        #endregion

        #region IOneWaySession Members

        void IOneWaySession.ProcessMessage(Message message)
        {
            Trace.WriteLine("IOneWaySession.ProcessMessage");
            try
            {
                FrameworkFacade.ProcessRequest(message, false);
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                throw;
            }

        }

        #endregion

        #region ITwoWay Members

        Message ITwoWay.ProcessMessage(Message message)
        {
            Trace.WriteLine("ITwoWay.ProcessMessage");
            try
            {
                return FrameworkFacade.ProcessRequest(message, true);
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                throw;
            }

        }

        #endregion

        #region ITwoWayVoid Members

        void ITwoWayVoid.ProcessMessage(Message message)
        {
            Trace.WriteLine("ITwoWayVoid.ProcessMessage");
            try
            {
                FrameworkFacade.ProcessRequest(message, false);

            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                throw;
            }
        }

        #endregion
    }
}

